<template>
  <a-layout-sider
    class="lc-menu-sider"
    breakpoint="lg"
    :width="320"
    :collapsed="collapsed"
    @collapse="onCollapse"
  >
    <a-tabs class="lc-tabs" :position="position">
      <a-tab-pane key="1" title="组件库">
        <a-collapse
          class="lc-menu-collapse"
          :default-active-key="[1]"
          accordion
        >
          <a-collapse-item
            v-for="(item, index) in list"
            :key="index"
            :header="item.label"
          >
            <div class="lc-menu-collapse-item">
              <draggableVue
                :list="item.children"
                ghost-class="ghost"
                :force-fallback="true"
                :group="{ name: 'list', pull: 'clone' }"
                :sort="false"
                itemKey="id"
                :clone="onClone"
                draggable
              >
                <template #item="{ element }">
                  <div class="lc-menu-collapse-item-preview">
                    <div class="lc-menu-collapse-item-preview-content">
                      <!-- <div class="lc-menu-collapse-item-preview-shade"></div> -->
                      <component :is="element.icon" :size="32"></component>
                      <span style="margin-left: 8px">
                        {{ element.label }}
                      </span>
                    </div>
                    <div class="lc-menu-collapse-item-label"></div>
                  </div>
                </template>
              </draggableVue>
            </div>
          </a-collapse-item>
        </a-collapse>
      </a-tab-pane>
      <a-tab-pane key="2" title="接口文档"> Content of Tab Panel 2 </a-tab-pane>
      <a-tab-pane key="3" title="目录">
        <a-tree
          class="tree-demo"
          :data="catalogList"
          v-model:selected-keys="selsctedKeys"
          :fieldNames="{
            key: 'id',
            title: 'name',
            children: 'children',
            icon: 'icon',
            style: 'style-none',
          }"
          draggable
          blockNode
          show-line
          @drop="onDrop"
        >
        </a-tree>
      </a-tab-pane>
    </a-tabs>
  </a-layout-sider>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, PropType, computed } from "vue";
import { useVModel } from "@vueuse/core";
import {
  IconCaretRight,
  IconCaretLeft,
  IconHome,
  IconCalendar,
} from "@arco-design/web-vue/es/icon";
import {
  customGlobalComponent,
  type Container,
  type ContainerType,
} from "@/components/custom/index.tsx";
import draggableVue from "@/components/draggable/index.vue";
import { customComponent } from "@/components/custom/incident";
export default defineComponent({
  components: {
    IconCaretRight,
    IconCaretLeft,
    IconHome,
    IconCalendar,
    draggableVue,
  },
  props: {
    data: {
      type: Array as PropType<Container[]>,
      default: () => [],
    },
    selectedKeys: {
      type: Array as PropType<string[]>,
      default: () => [],
    },
  },
  emits: ["update:data", "update:selectedKeys"],
  setup(props, { emit }) {
    interface List {
      type: ContainerType;
      label: string;
      children: Container[];
    }
    const position = ref();
    const catalogList = useVModel(props, "data", emit);
    const selsctedKeys = useVModel(props, "selectedKeys", emit);
    const list = ref<List[]>([
      {
        type: "container",
        label: "容器",
        children: [],
      },
      {
        type: "form",
        label: "表单",
        children: [],
      },
      {
        type: "common",
        label: "常用组件",
        children: [],
      },
      {
        type: "expert",
        label: "高级组件",
        children: [],
      },
      {
        type: "chart",
        label: "图表组件",
        children: [],
      },
      {
        type: "other",
        label: "其他组件",
        children: [],
      },
    ]);

    const getList = () => {
      let custom = customGlobalComponent();
      Object.keys(custom).forEach((key) => {
        list.value.map((item) => {
          if (item.type === custom[key].type && custom[key].hidden !== true) {
            item.children.push(custom[key]);
          }
          return {
            ...item,
          };
        });
      });
    };
    onMounted(() => {
      getList();
    });
    const collapsed = ref(false);
    const onCollapse = () => {
      collapsed.value = !collapsed.value;
    };
    // 克隆
    const onClone = (clone: Container) => {
      console.log("clone", clone);
      return customComponent(clone);
    };

    const onDrop = ({ dragNode, dropNode, dropPosition }) => {
      const data = catalogList.value;
      const loop = (data, id, callback) => {
        data.some((item, index, arr) => {
          if (item.id === id) {
            callback(item, index, arr);
            return true;
          }
          if (item.children) {
            return loop(item.children, id, callback);
          }
          return false;
        });
      };
      loop(data, dragNode.id, (_, index, arr) => {
        arr.splice(index, 1);
      });

      if (dropPosition === 0) {
        loop(data, dropNode.id, (item) => {
          item.children = item.children || [];
          item.children.push(dragNode);
        });
      } else {
        loop(data, dropNode.id, (_, index, arr) => {
          arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode);
        });
      }
    };
    return {
      position,
      list,
      collapsed,
      catalogList,
      selsctedKeys,
      onDrop,
      onClone,
      onCollapse,
    };
  },
});
</script>
<style lang="scss" scoped>
.lc-menu-sider {
  :deep(.lc-menu-collapse) {
    .arco-collapse-item-content {
      padding-left: 0;
    }
  }
  .lc-menu-collapse {
    margin-top: -10px;

    .lc-menu-collapse-item {
      min-height: 180px;
      .drag-box {
        display: flex;
        flex-wrap: wrap;
      }
      .lc-menu-collapse-item-label {
        font-size: 12px;
        color: var(color-text-2);
      }
      .lc-menu-collapse-item-preview {
        padding: 8px;
        border: 1px solid var(--color-neutral-4);
        border-radius: 4px;
        margin-bottom: 10px;
        background: var(--color-bg-4);
        cursor: pointer;
        &:hover {
          border-color: #1890ff;
        }

        .lc-menu-collapse-item-preview-content {
          position: relative;
          display: flex;
          align-items: center;
          .lc-menu-collapse-item-preview-shade {
            position: absolute;
            width: 100%;
            height: 100%;
            z-index: 99;
          }
        }
        .lc-menu-collapse-item-label {
          text-align: right;
        }
      }
    }
  }
  .tree-demo {
    padding: 6px 10px;
  }
  .tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title),
  .tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title):hover {
    animation: blinkBg 0.4s 2;
  }

  @keyframes blinkBg {
    0% {
      background-color: transparent;
    }

    100% {
      background-color: var(--color-primary-light-1);
    }
  }
}
</style>
